package com.wbp.cms.core.dao.base;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import com.wbp.cms.client.common.BaseDO;
import com.wbp.cms.client.common.Page;

public  class BaseDaoImpl<T extends BaseDO> implements BaseDao<T> {

	protected static final Logger logger = Logger.getLogger(BaseDaoImpl.class);

	public static final String SQL_INSERT = "insert";
	public static final String SQL_BATCH_INSERT = "batchInsert";
	public static final String SQL_UPDATE = "update";
	public static final String SQL_BATCH_UPDATE = "batchUpdate";
	public static final String SQL_BATCH_UPDATE_BY_PARAMS = "batchUpdateByParams";
	public static final String SQL_QUERY_ENTITY_BY_ID= "queryEntityById"; // "load";
	public static final String SQL_QUERY_ENTITY_BY_PARAMS = "queryEntityByParamss";
	public static final String SQL_QUERY_LIST_BY_PARAMS =  "queryListByParams" ;
	
	public static final String SQL_QUERY_COUNT_BY_PARAMS = "queryCountByParams";
	public static final String SQL_QUERY_COUNT = "queryCount";
	
	public static final String SQL_DELETE = "delete";
	public static final String SQL_BATCH_DELETE = "batchDelete";
	public static final String SQL_BATCH_DELETE_BY_PARAMS = "batchDeleteByParams";
	
	public static final String SQL_QUERY_LIST = "queryList";
	public static final String SQL_QUERY_ENTITY = "queryEntity";
	
	//public static final String SQL_LIST_PAGE_COUNT = "listPageCount";
	//public static final String SQL_COUNT_BY_PAGE_PARAM = "countByPageParam"; // 根据当前分页参数进行统计
	//public static final String SQL_QUERYY_BY_PAGE = "queryByPage";

	/**
	 * 注入SqlSessionTemplate实例(要求Spring中进行SqlSessionTemplate的配置).
	 * 可以调用sessionTemplate完成数据库操作.
	 */
	@Autowired
	private SqlSessionTemplate sessionTemplate;

	@Override
	public SqlSessionTemplate getSessionTemplate() {
		return sessionTemplate;
	}

	public void setSessionTemplate(SqlSessionTemplate sessionTemplate) {
		this.sessionTemplate = sessionTemplate;
	}
	@Override
	public int insert(T entity) {
		int result = 0;
		try {
			result = sessionTemplate.insert(getStatement(SQL_INSERT), entity);
			if (result <= 0) {
				throw new RuntimeException("数据库操作,insert返回0."
						+ getStatement(SQL_INSERT));
			}
		} catch (Throwable t) {
			if (t.getMessage().indexOf("Duplicate entry") != -1) {
				logger.error("insert Duplicate entry error:", t);
				String msg = t.getMessage();
				int start = msg.indexOf("Duplicate entry");
				msg = msg.substring(start);
				start = msg.indexOf("#");
				msg = msg.substring(0, start);
				throw new RuntimeException(msg);
			}
			logger.error("insert error:", t);
		}

		return result;
	}

	 /**
     * 批量插入数据.
     */
	@Override
    public int batchInsert(List<T> list) {
        if (list.isEmpty() || list.size() <= 0) {
            return 0;
        }
        int result = sessionTemplate.insert(getStatement(SQL_BATCH_INSERT), list);
        if (result <= 0) {
            throw new RuntimeException("数据库操作,batchInsert返回0."+ getStatement(SQL_BATCH_INSERT));
        }
        return result;
    }

    /**
     * 根据id单条更新数据.
     */
	@Override
    public int update(T entity) {
        //entity.setEditTime(new Date());
        int result = sessionTemplate.update(getStatement(SQL_UPDATE), entity);
        if (result <= 0) {
            throw new RuntimeException("数据库操作,updateByPrimaryKey返回0."+ getStatement(SQL_UPDATE));
        }
        return result;
    }

    /**
     * 根据id批量更新数据.
     */
	@Override
    public int batchUpdate(List<T> list) {
        if (list.isEmpty() || list.size() <= 0) {
            return 0;
        }
        int result = sessionTemplate.update(getStatement(SQL_BATCH_UPDATE), list);
        if (result <= 0) {
            throw new RuntimeException("数据库操作,batchUpdateByIds返回0."+getStatement(SQL_BATCH_UPDATE));
        }
        return result;
    }

    /**
     * 根据column批量更新数据.
     */
	@Override
    public int updateByParams(Map<String, Object> paramMap) {
        if (paramMap == null) {
            return 0;
        }
        int result = sessionTemplate.update(getStatement(SQL_BATCH_UPDATE_BY_PARAMS), paramMap);
        if (result <= 0) {
            throw new RuntimeException("数据库操作,batchUpdateByColumn返回0."+getStatement(SQL_BATCH_UPDATE_BY_PARAMS));
        }
        return result;
    }

	 /**
     * 根据id删除数据.
     */
	@Override
    public int delete(String id) {
        return sessionTemplate.delete(getStatement(SQL_DELETE), id);
    }

    /**
     * 根据id批量删除数据.
     */
	@Override
    public int batchDelete(List<T> list) {
        if (list.isEmpty() || list.size() <= 0) {
            return 0;
        } else {
            return sessionTemplate.delete(getStatement(SQL_BATCH_DELETE), list);
        }
    }

    /**
     * 根据column批量删除数据.
     */
	@Override
    public int deleteByParams(Map<String, Object> paramMap) {
        if (paramMap == null) {
            return 0;
        } else {
            return  sessionTemplate.delete(getStatement(SQL_BATCH_DELETE_BY_PARAMS), paramMap);
        }
    }

    
    /**
     * 根据id查询数据.
     */
	@Override
    public T queryEntityById(Long id) {
        return sessionTemplate.selectOne(getStatement(SQL_QUERY_ENTITY_BY_ID), id);
    }

    /**
     * 根据column查询数据.
     */
    @Override
    public T queryEntityByParams(Map<String, Object> paramMap) {
        if (paramMap == null) {
            return null;
        }
        return sessionTemplate.selectOne(getStatement(SQL_QUERY_ENTITY_BY_PARAMS), paramMap);
    }
    
    public T queryEntity(@SuppressWarnings("rawtypes") Page  page){
    	if(page == null)
    		return null ;
    	return sessionTemplate.selectOne(getStatement(SQL_QUERY_ENTITY), page);
    }
    /**
     * 根据条件查询列表数据.
     */
    @Override
    public List<T> queryListByParams(Map<String, Object> paramMap) {
        if (paramMap == null) {
            return null;
        }
        List<T> list = sessionTemplate.selectList(getStatement(SQL_QUERY_LIST_BY_PARAMS), paramMap);
        return list.stream().filter(p->{return p!=null ;}).collect(Collectors.toList()) ;
    }

    @Override
    public List<T> queryList(@SuppressWarnings("rawtypes") Page pager){
    	if(pager == null)
    		return null ;
    	return sessionTemplate.selectList(getStatement(SQL_QUERY_LIST), pager);
    }

    /**
     * 根据column查询记录数.
     */
    @Override
    public Long queryCountByParams(Map<String, Object> paramMap) {
        if (paramMap == null) {
            return null;
        }
        return sessionTemplate.selectOne(getStatement(SQL_QUERY_COUNT_BY_PARAMS), paramMap);
    }

    public Long queryCount(@SuppressWarnings("rawtypes") Page page) {
    	if (page == null) {
            return null;
        }
        return sessionTemplate.selectOne(getStatement(SQL_QUERY_COUNT), page);
    }
    /**
     * 分页查询
     */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Page queryByPage(Page pageParam, Map<String, Object> paramMap) {
		if (paramMap == null) {
            paramMap = new HashMap<String, Object>();
        }
        // 统计总记录数
        Long totalCount = this.queryCountByParams(paramMap)  ;
        if(totalCount <=0)
        	return new Page(pageParam.getPageNo(),pageParam.getPageSize(),null,0) ;
        
        pageParam.setTotalCount(totalCount.intValue());
        
        // 根据页面传来的分页参数构造SQL分页参数
        /*paramMap.put("pageFirst", pageParam.getFirst());
        paramMap.put("pageSize", pageParam.getPageSize());
        paramMap.put("startRowNum", pageParam.getStart());
        paramMap.put("endRowNum", pageParam.getLast());
        */
        
        // 根据页面传来的分页参数构造SQL分页参数
        paramMap.put("pageFirst", (pageParam.getPageNo() - 1) * pageParam.getPageSize());
        paramMap.put("pageSize", pageParam.getPageSize());
        paramMap.put("startRow", (pageParam.getPageNo() - 1) * pageParam.getPageSize());
        paramMap.put("endRow", pageParam.getPageNo() * pageParam.getPageSize());
        
        //当前分页的记录数    // sessionTemplate.selectOne(getStatement(SQL_COUNT_BY_PAGE_PARAM), paramMap);
        Long currentPageCount  = this.queryCountByParams(paramMap)  ; 
        if(currentPageCount <=0)
        	return new Page(pageParam.getPageNo(),pageParam.getPageSize(),null,totalCount.intValue()) ;
        
        // 获取分页数据集
        List<T> list =this.queryListByParams(paramMap) ;
        		// sessionTemplate.selectList(getStatement(SQL_QUERYY_BY_PAGE), paramMap);
        
	    return new Page(pageParam.getPageNo(),pageParam.getPageSize(),list,totalCount.intValue()) ;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Page queryByPage(Page pageParam) {
		if (pageParam == null) {
           return null ;
        }
        // 统计总记录数
        Long totalCount = this.queryCount(pageParam) ;
        if(totalCount <=0)
        	return new Page(pageParam.getPageNo(),pageParam.getPageSize(),null,0) ;
        
        pageParam.setTotalCount(totalCount.intValue());
        
        //当前分页的记录数
        Long currentPageCount  = this.queryCount(pageParam)  ; 
        if(currentPageCount <=0)
        	return new Page(pageParam.getPageNo(),pageParam.getPageSize(),null,totalCount.intValue()) ;
        
        // 获取分页数据集
        List<T> list =this.queryList(pageParam) ;
	    return new Page(pageParam.getPageNo(),pageParam.getPageSize(),list,totalCount.intValue()) ;
	}
	
	/**
	 * 函数功能说明 ： 获取Mapper命名空间.
	 * 可以被子类重写
	 * @参数：@param sqlId
	 * @参数：@return
	 * @return：String
	 * @throws
	 */
	public String getStatement(String sqlId) {
		String name = this.getClass().getName();
		// 单线程用StringBuilder，确保速度；多线程用StringBuffer,确保安全
		StringBuilder sb = new StringBuilder();
		sb.append(name).append(".").append(sqlId);
		return sb.toString();
	}

	 

}
